#include "ADConvert.h"

#include "Tools.h"

static bool is_inited = false;

void
adconvert_init(void)
{
        if (is_inited)
                return;

        // 开启时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

        // 设置 ADC 时钟
        RCC_ADCCLKConfig(RCC_PCLK2_Div6);

        // GPIO 初始化
        GPIO_InitTypeDef gpio = {.GPIO_Mode  = GPIO_Mode_AIN,
                                 .GPIO_Pin   = GPIO_Pin_0 | GPIO_Pin_1,
                                 .GPIO_Speed = GPIO_Speed_50MHz};
        // 将PA0、PA1、PA2和PA3引脚初始化为模拟输入
        GPIO_Init(GPIOA, &gpio);

        /*不在此处配置规则组序列，而是在每次AD转换前配置，这样可以灵活更改AD转换的通道*/

        /*ADC初始化*/
        ADC_InitTypeDef adc = {.ADC_Mode      = ADC_Mode_Independent,
                               .ADC_DataAlign = ADC_DataAlign_Right,
                               .ADC_ExternalTrigConv =
                                       ADC_ExternalTrigConv_None,
                               .ADC_ContinuousConvMode = DISABLE,
                               .ADC_ScanConvMode       = DISABLE,
                               .ADC_NbrOfChannel       = 1};
        ADC_Init(ADC1, &adc);

        /*ADC使能*/
        ADC_Cmd(ADC1, ENABLE);

        /*ADC校准*/
        ADC_ResetCalibration(ADC1);
        while (ADC_GetResetCalibrationStatus(ADC1) == SET)
                ;
        ADC_StartCalibration(ADC1);
        while (ADC_GetCalibrationStatus(ADC1) == SET)
                ;

        is_inited = true;
}

uint16_t
adconvert_get_value_once(ADChannelType adc_channel)
{
        delay_us(500);
        ADC_RegularChannelConfig(ADC1,
                                 (uint8_t)adc_channel,
                                 1,
                                 ADC_SampleTime_239Cycles5);
        ADC_SoftwareStartConvCmd(ADC1, ENABLE);
        while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET)
                ;
        return ADC_GetConversionValue(ADC1);
}
